package com.chnbst.bstyun.eos;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;



import org.apache.commons.codec.binary.Base64;
import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import com.chnbst.bstyun.core.common.SignUtil;
import com.chnbst.bstyun.core.common.export.ExcelAnnotation;
import com.chnbst.bstyun.core.common.export.ExcelStyle;

/* 
 * 导出excel 工具类
 * @author yanwl
 * @date 2015-02-04
 */
public class ExcelExport<T> {

    /**
     * 反射类
     */
    private Class<T> entityClazz;

    public ExcelExport(Class<T> entityClazz) {
        this.entityClazz = entityClazz;
    }

    /**
     * @param dataSet
     *            数据集合 Collection集合子类 属性值为null返回空字符串''，为Boolean类型时true返回是，false返回否， 日期格式为设定格式或者默认格式。
     * @param out
     *            输出流对象（存在硬盘中如：new FileOutputStream(filePath)，存于内存中如：ActionContext.getResponse().getOutputStream()）
     * @param sheetName
     *            Excel sheet 页的名称 (默认为sheet1)
     * @throws IOException 
     * @throws FileNotFoundException 
     * @throws Exception
     */
    
    @SuppressWarnings("deprecation")
	public void exportExcel(HttpServletRequest request,
			HttpServletResponse response,Collection<T> dataSet,String fileName,int fromIndex,String[] title) throws Exception {
    	String enableFileName = "";
    	// 导出
        OutputStream out = null;
        try {
            response.setContentType("application/octet-stream");

        	String agent = (String)request.getHeader("USER-" +
        			"AGENT");     
            if(agent != null && agent.indexOf("MSIE") == -1) {// FF      
                enableFileName = "=?UTF-8?B?" + (new String(Base64.encodeBase64(fileName.getBytes("UTF-8")))) + "?=";    
                response.setHeader("Content-Disposition", "attachment; filename=" + enableFileName);    
            } else { // IE      
          	  enableFileName = new String(fileName.getBytes("GBK"), "ISO-8859-1");    
                response.setHeader("Content-Disposition", "attachment; filename=" + enableFileName);    
            }  
            out = response.getOutputStream();
            
            // 首先检查数据看是否是正确的
            if (dataSet == null || out == null) {
                throw new IOException("传入的数据不对！");
            }
         
            // 得到所有字段
            Field filed[] = entityClazz.getDeclaredFields();
            // 导出的字段的get方法
            List<Method> methodObj = new ArrayList<Method>();
            // 遍历整个filed
            for (int i = 0; i < filed.length; i++) {
                Field f = filed[i];
                ExcelAnnotation exa = f.getAnnotation(ExcelAnnotation.class);
                // 如果设置了Annotation
                if (exa != null) {
                    // 添加到需要导出的字段的方法
                    String fieldname = f.getName();
                    String getMethodName = "get" + fieldname.substring(0, 1).toUpperCase() + fieldname.substring(1);
                    Method getMethod = entityClazz.getMethod(getMethodName, new Class[] {});
                    methodObj.add(getMethod);
                }
            }
            
            /**
             * 1 读取手动创建好的表格
             */
            // 声明一个工作薄
            //文件保存目录路径
    		/*String savePath = request.getSession().getServletContext().getRealPath("/");
            String path = savePath+"/upload/excel/"+fileName;
            System.out.println(path);
            HSSFWorkbook workbook = new HSSFWorkbook( new FileInputStream(path));
            HSSFSheet sheet = workbook.getSheet ("Sheet1");*/
            
            /**
             * 2 自动创建表格
             */
            HSSFWorkbook workbook = new HSSFWorkbook();
            // 生成一个表格
            HSSFSheet sheet = workbook.createSheet(fileName);
            sheet.setDefaultColumnWidth(30);
            HSSFCellStyle headStyle = ExcelStyle.setHeadStyle(workbook);
            HSSFRow  row = sheet.createRow(0);
            for (int i = 0; i < title.length; i++) {
                HSSFCell cell = row.createCell(i);
                cell.setCellStyle(headStyle);
                HSSFRichTextString text = new HSSFRichTextString(title[i]);
                cell.setCellValue(text);
            }
            
            int index = fromIndex;
            // 循环整个集合
            HSSFCellStyle bodyStyle = ExcelStyle.setBodyStyle(workbook);
            Iterator<T> its = dataSet.iterator();
            while (its.hasNext()) {
                // 从第二行开始写，第一行是标题
            	row = sheet.createRow(index);
                T t = its.next();
                for (int k = 0; k < methodObj.size(); k++) {
                	HSSFCell cell = row.createCell(k);
                    // 设置内容样式
                    cell.setCellStyle(bodyStyle);
                    Method getMethod = methodObj.get(k);
                    Object value = getMethod.invoke(t, new Object[] {});
                    if (value instanceof Double||value instanceof Integer||value instanceof Float||value instanceof Long) {
                    	Double d=Double.valueOf(value+"").doubleValue();
                        cell.setCellValue(d);

                    }else{
                    	String textValue = getTextValue(value)+"";
                        cell.setCellValue(textValue);
                    }

                    
                }
                index++;
            }
            workbook.write(out);
            
            out.flush();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
        	try {
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
        }
    }
    
    /*字段格式转换*/
    private String getTextValue(Object value) {
        String textValue = "";
        if (value == null) {
            return textValue;
        }
        if (value instanceof Boolean) {
            boolean bValue = (Boolean) value;
            textValue = "是";
            if (!bValue) {
                textValue = "否";
            }
        }else if(value instanceof Date) {
        	textValue = SignUtil.time2str((Date)value, "yyyy-MM-dd HH:mm:ss");
        }

        else {
            textValue = value.toString();
        }
        return textValue;
    }
}
